#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2025/1/21 9:25
# @Author : ZhengQL
import base64
import time
from playwright.sync_api import sync_playwright
import ddddocr
import pytest
from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeoutError

# @pytest.fixture(scope="session")
def cookie_login():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False, args=["--enable-logging", "--v=1"])
        context = browser.new_context(ignore_https_errors=True)
        page = context.new_page()
        page.goto("http://uatdxuas.wehdz.gov.cn:33698/#/login")
        time.sleep(2)
        # page.pause()

        page.get_by_placeholder("请输入账号或手机号").fill("ZhengQL")
        page.get_by_placeholder("请输入密码").fill("Zq1234@@")
        page.get_by_role("button", name="登录").click()
        # page.pause()
        time.sleep(1)

        # 拿到背景图
        img_src = page.query_selector(
            "#app > div > div > div > div.mask > div > div.verifybox-bottom > div > div.verify-img-out > div > img").get_attribute(
            'src')
        # print('验证码图片的 src:', img_src)

        # 转换成图片
        with open('bj_base.png', 'wb') as fp:
            bj_b = str(img_src).split(',')[-1]
            bj_base = base64.b64decode(bj_b)
            fp.write(bj_base)
        # 缺口图片
        img_src_Q = page.query_selector(
            "#app > div > div > div > div.mask > div > div.verifybox-bottom > div > div.verify-bar-area > div > div > div > img").get_attribute(
            'src')
        # print('二维码图片的 src:', img_src_Q)
        # 转换成图片
        with open('bj_base_a.png', 'wb') as fp:
            bj_b2 = str(img_src_Q).split(',')[-1]
            bj_base_a = base64.b64decode(bj_b2)
            fp.write(bj_base_a)

        # 计算滑动距离
        det = ddddocr.DdddOcr(det=False, ocr=False)
        ressta = det.slide_match(bj_base, bj_base_a, simple_target=True)["target"][0]
        # print("计算距离" + str(ressta))
        bili = round(400 / 315, 2)
        # print("图片比例" + str(bili))
        test = ressta * bili
        # print("可能的记录" + str(test))
        res = test + 30 + 3
        print("调整后的记录" + str(res))

        slide_btn = page.locator("#app > div > div > div > div.mask > div > div.verifybox-bottom > div > div.verify-bar-area > div > div")
        btn = slide_btn.bounding_box()
        print(btn)

        # 鼠标移动
        page.mouse.move(x=btn['x'], y=btn['y'] + 5)
        page.mouse.down()
        time.sleep(1)

        page.mouse.move(x=btn['x'] + res, y=btn['y'] + 5)
        page.mouse.up()

        # 等待验证完成
        time.sleep(2)
        print(page.title())

        # 等待到加载到指定页面,否则无法保存成功
        page.wait_for_url(url='http://uatdxuas.wehdz.gov.cn:33698/#/')
        # 保存登陆的cookies
        # print(f"项目的根目录：{pytestconfig.rootpath}")
        # storage_path = pytestconfig.rootpath.joinpath('auth/login111.json')
        # context.storage_state(path=storage_path)
        page.context.storage_state(path="D:\\11 PyCharm\ZQL\DG_WebTest/auth/login111.json")



        """
        测试内容：检查接口响应报错和前端控制台报错
        1、低空航线管理平台
        2、
        3、
        """

        # 打开低空航线管理平台
        with context.expect_page() as new_page_info:
            page.click("//*[@id='app']/div/div[1]/div[2]/div[2]/div/div/div[1]/div[1]/div/div[1]")  # 触发新页面打开

        new_page = new_page_info.value
        new_page.wait_for_load_state()  # 等待新页面加载完成
        print(new_page.title())

        """点击进入所有页面 """
        try:
            # 航线分布
            new_page.click("//*[@id='tab-Distribution']/div/span")
            new_page.wait_for_load_state()  # 等待新页面加载完成
            print(new_page.title())
            time.sleep(10)
            # 航线展示-航线列表
            new_page.click("//*[@id='tab-Exhibition']/div/span")
            new_page.wait_for_load_state()  # 等待新页面加载完成
            print(new_page.title())
            # 航线展示-航线标注
            new_page.click("//*[@id='app']/div/div[1]/div/div[1]/div/div[1]/div[1]/div/ul/li[2]/div/span")
            new_page.wait_for_load_state()  # 等待新页面加载完成
            print(new_page.title())
            # 航线验证
            new_page.click("//*[@id='tab-Verify']/div/span")
            new_page.wait_for_load_state()  # 等待新页面加载完成
            print(new_page.title())

            # 检查浏览器控制台错误
            print("==== 检查浏览器控制台日志 ====")

            # 设置控制台消息监听器 [citation:9]
            def handle_console_msg(msg):
                if msg.type == 'error':
                    print(f"控制台错误: {msg.text}")

            page.on("console", handle_console_msg)

            # 检查网络请求和响应
            print("\n==== 检查网络请求 ====")

            def handle_response(response):
                if response.status >= 400:
                    print(f"请求失败: {response.url} - 状态码: {response.status}")

            page.on("response", handle_response)

            # 为了确保能捕获到日志，可以再次触发页面活动或等待一段时间
            page.wait_for_timeout(1000)

        except PlaywrightTimeoutError as e:
            # 保存截图和页面源码以便调试 [citation:9][citation:10]
            page.screenshot(path="error_screenshot.png", full_page=True)

            with open("error_page_source.html", "w", encoding="utf-8") as f:
                f.write(page.content())

            print("操作超时，已保存截图和页面源码。")
            raise e

        finally:
            # 关闭浏览器
            browser.close()







        #  # 关闭
        # time.sleep(4)
        # browser.close()





class BrowserMonitor:
    def __init__(self):
        self.console_errors = []
        self.network_errors = []

    def setup_console_monitoring(self, page):
        """设置控制台错误监控"""

        def handle_console_msg(msg):
            if msg.type == 'error':
                error_info = {
                    'text': msg.text,
                    'type': msg.type,
                    'url': msg.location['url'] if msg.location else 'N/A',
                    'line': msg.location['line'] if msg.location else 'N/A'
                }
                self.console_errors.append(error_info)

        page.on("console", handle_console_msg)

    def setup_network_monitoring(self, page):
        """设置网络请求监控"""

        def handle_response(response):
            if response.status >= 400:
                error_info = {
                    'url': response.url,
                    'status': response.status,
                    'status_text': response.status_text,
                    'method': response.request.method if response.request else 'N/A'
                }
                self.network_errors.append(error_info)

        page.on("response", handle_response)

    def check_browser_errors(self):
        """检查浏览器错误并输出报告"""
        print("\n" + "=" * 50)
        print("浏览器错误检查报告")
        print("=" * 50)

        if self.console_errors:
            print(f"\n=== 发现 {len(self.console_errors)} 个控制台错误 ===")
            for i, error in enumerate(self.console_errors, 1):
                print(f"{i}. 错误: {error['text']}")
                print(f"   位置: {error['url']}:{error['line']}")
        else:
            print("\n✓ 未发现控制台错误")

        if self.network_errors:
            print(f"\n=== 发现 {len(self.network_errors)} 个网络请求错误 ===")
            for i, error in enumerate(self.network_errors, 1):
                print(f"{i}. URL: {error['url']}")
                print(f"   状态: {error['status']} {error['status_text']}")
                print(f"   方法: {error['method']}")
        else:
            print("\n✓ 未发现网络请求错误")

        # 返回是否有错误
        has_errors = len(self.console_errors) > 0 or len(self.network_errors) > 0
        return has_errors

    def clear_logs(self):
        """清空收集的日志"""
        self.console_errors.clear()
        self.network_errors.clear()


def run_playwright_with_monitoring():
    """主函数：使用Playwright执行自动化任务并监控错误"""
    monitor = BrowserMonitor()

    with sync_playwright() as p:
        # 启动浏览器
        browser = p.chromium.launch(
            headless=False,
            args=['--enable-logging', '--v=1']
        )

        # 创建上下文和页面
        context = browser.new_context()
        page = context.new_page()

        try:
            # 设置监控
            monitor.setup_console_monitoring(page)
            monitor.setup_network_monitoring(page)

            # 第一步：打开初始页面
            print("正在打开初始页面...")
            page.goto("https://www.example.com", wait_until="networkidle")

            # 等待页面完全加载
            page.wait_for_function("document.readyState === 'complete'")

            # 检查初始页面的错误
            print("\n" + "=" * 30)
            print("初始页面加载完成")
            print("=" * 30)
            initial_errors = monitor.check_browser_errors()

            if initial_errors:
                print("警告：初始页面存在错误！")
            else:
                print("初始页面检查通过！")

            # 清空日志，为下一步操作准备
            monitor.clear_logs()

            # 第二步：点击链接并等待新页面加载
            print("\n正在点击链接...")
            link_to_click = page.locator("#my-link")
            link_to_click.click()

            # 等待新页面加载完成
            page.wait_for_url("**/*")  # 等待URL变化
            page.wait_for_load_state("networkidle")
            page.wait_for_function("document.readyState === 'complete'")

            # 额外等待确保所有资源加载完成
            page.wait_for_timeout(2000)

            # 检查新页面的错误
            print("\n" + "=" * 30)
            print("新页面加载完成")
            print("=" * 30)
            new_page_errors = monitor.check_browser_errors()

            if new_page_errors:
                print("警告：新页面存在错误！")
                # 可以在这里添加额外的错误处理逻辑
            else:
                print("新页面检查通过！")

        except PlaywrightTimeoutError as e:
            # 错误处理：保存截图和页面源码
            print("操作超时，正在保存调试信息...")
            page.screenshot(path="error_screenshot.png", full_page=True)

            with open("error_page_source.html", "w", encoding="utf-8") as f:
                f.write(page.content())

            # 即使超时也检查已收集的错误
            print("\n超时前的错误检查：")
            monitor.check_browser_errors()

            print("调试信息已保存至 error_screenshot.png 和 error_page_source.html")
            raise e

        except Exception as e:
            # 其他异常处理
            print(f"发生异常: {e}")
            page.screenshot(path="exception_screenshot.png", full_page=True)
            raise e

        finally:
            # 关闭浏览器
            browser.close()


def check_specific_page(url, selector_to_click=None):
    """专用函数：检查特定页面的错误"""
    monitor = BrowserMonitor()

    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()

        try:
            # 设置监控
            monitor.setup_console_monitoring(page)
            monitor.setup_network_monitoring(page)

            # 导航到目标页面
            print(f"正在检查页面: {url}")
            page.goto(url, wait_until="networkidle")
            page.wait_for_function("document.readyState === 'complete'")

            # 如果需要点击元素
            if selector_to_click:
                print(f"正在点击元素: {selector_to_click}")
                page.locator(selector_to_click).click()
                page.wait_for_load_state("networkidle")
                page.wait_for_function("document.readyState === 'complete'")

            # 等待确保所有异步操作完成
            page.wait_for_timeout(3000)

            # 检查错误
            has_errors = monitor.check_browser_errors()
            return has_errors

        finally:
            browser.close()


# if __name__ == "__main__":
#     # 方式1：使用完整流程
#     run_playwright_with_monitoring()
#
#     # 方式2：快速检查特定页面
#     # has_errors = check_specific_page(
#     #     url="https://www.example.com",
#     #     selector_to_click="#my-link"
#     # )
#     # print(f"页面检查完成，是否存在错误: {has_errors}")







if __name__ == '__main__':
    cookie_login()
